{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/filipe/.virtualenvs/iris/lib/python2.7/site-packages/folium/__init__.py\n",
      "0.2.0\n"
     ]
    }
   ],
   "source": [
    "import folium\n",
    "\n",
    "print(folium.__file__)\n",
    "print(folium.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from folium.features import Template\n",
    "\n",
    "class Map3d(folium.Map):\n",
    "    def __init__(self, location=None, width='100%', height='100%', left='0%',\n",
    "                 top='0%', position='relative', tiles='OpenStreetMap', API_key=None,\n",
    "                 max_zoom=18, min_zoom=1, zoom_start=10, attr=None, min_lat=-90,\n",
    "                 max_lat=90, min_lon=-180, max_lon=180, detect_retina=False, crs='EPSG3857'):\n",
    "        super(Map3d, self).__init__(location=location, width=width, height=height,\n",
    "                                    left=left, top=top, position=position, tiles=tiles,\n",
    "                                    API_key=API_key, max_zoom=max_zoom, min_zoom=min_zoom,\n",
    "                                    zoom_start=zoom_start, attr=attr, min_lat=min_lat,\n",
    "                                    max_lat=max_lat, min_lon=min_lon, max_lon=max_lon,\n",
    "                                    detect_retina=detect_retina, crs=crs)\n",
    "        self._template = Template(u\"\"\"\n",
    "        {% macro header(this, kwargs) %}\n",
    "            <script src=\"https://www.webglearth.com/v2/api.js\"></script>\n",
    "            <style> #{{this.get_name()}} {\n",
    "                position : {{this.position}};\n",
    "                width : {{this.width[0]}}{{this.width[1]}};\n",
    "                height: {{this.height[0]}}{{this.height[1]}};\n",
    "                left: {{this.left[0]}}{{this.left[1]}};\n",
    "                top: {{this.top[0]}}{{this.top[1]}};\n",
    "                }\n",
    "            </style>\n",
    "        {% endmacro %}\n",
    "        {% macro html(this, kwargs) %}\n",
    "            <div class=\"folium-map\" id=\"{{this.get_name()}}\" ></div>\n",
    "        {% endmacro %}\n",
    "\n",
    "        {% macro script(this, kwargs) %}\n",
    "\n",
    "            var southWest = L.latLng({{ this.min_lat }}, {{ this.min_lon }});\n",
    "            var northEast = L.latLng({{ this.max_lat }}, {{ this.max_lon }});\n",
    "            var bounds = L.latLngBounds(southWest, northEast);\n",
    "\n",
    "            var {{this.get_name()}} = WE.map('{{this.get_name()}}', {\n",
    "                                           center:[{{this.location[0]}},{{this.location[1]}}],\n",
    "                                           zoom: {{this.zoom_start}},\n",
    "                                           maxBounds: bounds,\n",
    "                                           layers: [],\n",
    "                                           crs: L.CRS.{{this.crs}}\n",
    "                                         });\n",
    "        {% endmacro %}\n",
    "        \"\"\")\n",
    "\n",
    "\n",
    "class TileLayer3d(folium.TileLayer):\n",
    "    def __init__(self, tiles='OpenStreetMap', min_zoom=1, max_zoom=18, attr=None,\n",
    "                 API_key=None, detect_retina=False, name=None, overlay=False, control=True):\n",
    "        super(TileLayer3d, self).__init__(tiles=tiles,\n",
    "            min_zoom=min_zoom, max_zoom=max_zoom, attr=attr,\n",
    "            API_key=API_key, detect_retina=detect_retina, name=name,\n",
    "            overlay=overlay, control=control)\n",
    "        self._template = Template(u\"\"\"\n",
    "        {% macro script(this, kwargs) %}\n",
    "            var {{this.get_name()}} = WE.tileLayer(\n",
    "                '{{this.tiles}}',\n",
    "                {\n",
    "                    maxZoom: {{this.max_zoom}},\n",
    "                    minZoom: {{this.min_zoom}},\n",
    "                    attribution: '{{this.attr}}',\n",
    "                    detectRetina: {{this.detect_retina.__str__().lower()}}\n",
    "                    }\n",
    "                ).addTo({{this._parent.get_name()}});\n",
    "\n",
    "        {% endmacro %}\n",
    "        \"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;base64,CiAgICAgICAgPCFET0NUWVBFIGh0bWw+CiAgICAgICAgPGhlYWQ+CiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICA8bWV0YSBodHRwLWVxdWl2PSJjb250ZW50LXR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIgLz4KICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9sZWFmbGV0LzAuNy4zL2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgICAgIAogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vYWpheC5nb29nbGVhcGlzLmNvbS9hamF4L2xpYnMvanF1ZXJ5LzEuMTEuMS9qcXVlcnkubWluLmpzIj48L3NjcmlwdD4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxzY3JpcHQgc3JjPSJodHRwczovL3Jhd2dpdGh1Yi5jb20vbHZvb2dkdC9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAvZGV2ZWxvcC9kaXN0L2xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLmpzIj48L3NjcmlwdD4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9sZWFmbGV0Lm1hcmtlcmNsdXN0ZXIvMC40LjAvbGVhZmxldC5tYXJrZXJjbHVzdGVyLXNyYy5qcyI+PC9zY3JpcHQ+CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvbGVhZmxldC5tYXJrZXJjbHVzdGVyLzAuNC4wL2xlYWZsZXQubWFya2VyY2x1c3Rlci5qcyI+PC9zY3JpcHQ+CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2xlYWZsZXQvMC43LjMvbGVhZmxldC5jc3MiIC8+CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMi4wL2Nzcy9ib290c3RyYXAubWluLmNzcyIgLz4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIiAvPgogICAgICAgIAogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2ZvbnQtYXdlc29tZS80LjEuMC9jc3MvZm9udC1hd2Vzb21lLm1pbi5jc3MiIC8+CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vcmF3Z2l0LmNvbS9sdm9vZ2R0L0xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLzIuMC9kZXZlbG9wL2Rpc3QvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuY3NzIiAvPgogICAgICAgIAogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9sZWFmbGV0Lm1hcmtlcmNsdXN0ZXIvMC40LjAvTWFya2VyQ2x1c3Rlci5EZWZhdWx0LmNzcyIgLz4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvbGVhZmxldC5tYXJrZXJjbHVzdGVyLzAuNC4wL01hcmtlckNsdXN0ZXIuY3NzIiAvPgogICAgICAgIAogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcHl0aG9uLXZpc3VhbGl6YXRpb24vZm9saXVtL21hc3Rlci9mb2xpdW0vdGVtcGxhdGVzL2xlYWZsZXQuYXdlc29tZS5yb3RhdGUuY3NzIiAvPgogICAgICAgIAogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgPHN0eWxlPgoKICAgICAgICAgICAgaHRtbCwgYm9keSB7CiAgICAgICAgICAgICAgICB3aWR0aDogMTAwJTsKICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTsKICAgICAgICAgICAgICAgIG1hcmdpbjogMDsKICAgICAgICAgICAgICAgIHBhZGRpbmc6IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAjbWFwIHsKICAgICAgICAgICAgICAgIHBvc2l0aW9uOmFic29sdXRlOwogICAgICAgICAgICAgICAgdG9wOjA7CiAgICAgICAgICAgICAgICBib3R0b206MDsKICAgICAgICAgICAgICAgIHJpZ2h0OjA7CiAgICAgICAgICAgICAgICBsZWZ0OjA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LndlYmdsZWFydGguY29tL3YyL2FwaS5qcyI+PC9zY3JpcHQ+CiAgICAgICAgICAgIDxzdHlsZT4gI21hcF85NmQ5Njc4YmFiZmM0ZDQ4OWE0OTIwNDkyMDRmYWMwZSB7CiAgICAgICAgICAgICAgICBwb3NpdGlvbiA6IHJlbGF0aXZlOwogICAgICAgICAgICAgICAgd2lkdGggOiAxMDAuMCU7CiAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwMC4wJTsKICAgICAgICAgICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgICAgICAgICB0b3A6IDAuMCU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgCiAgICAgICAgPC9oZWFkPgogICAgICAgIDxib2R5PgogICAgICAgICAgICAKICAgICAgICAKICAgICAgICAgICAgCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvbGl1bS1tYXAiIGlkPSJtYXBfOTZkOTY3OGJhYmZjNGQ0ODlhNDkyMDQ5MjA0ZmFjMGUiID48L2Rpdj4KICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICA8L2JvZHk+CiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIHNvdXRoV2VzdCA9IEwubGF0TG5nKC05MCwgLTE4MCk7CiAgICAgICAgICAgIHZhciBub3J0aEVhc3QgPSBMLmxhdExuZyg5MCwgMTgwKTsKICAgICAgICAgICAgdmFyIGJvdW5kcyA9IEwubGF0TG5nQm91bmRzKHNvdXRoV2VzdCwgbm9ydGhFYXN0KTsKCiAgICAgICAgICAgIHZhciBtYXBfOTZkOTY3OGJhYmZjNGQ0ODlhNDkyMDQ5MjA0ZmFjMGUgPSBXRS5tYXAoJ21hcF85NmQ5Njc4YmFiZmM0ZDQ4OWE0OTIwNDkyMDRmYWMwZScsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlcjpbLTQyLC00Ml0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcnM6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIHRpbGVfbGF5ZXJfOGJiODk5NGY0OTczNDNiNjgyODk4N2Q3NjRlYTlmMDkgPSBXRS50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1heFpvb206IDE4LAogICAgICAgICAgICAgICAgICAgIG1pblpvb206IDEsCiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRpb246ICdEYXRhIGJ5IDxhIGhyZWY9Imh0dHA6Ly9vcGVuc3RyZWV0bWFwLm9yZyI+T3BlblN0cmVldE1hcDwvYT4sIHVuZGVyIDxhIGhyZWY9Imh0dHA6Ly93d3cub3BlbnN0cmVldG1hcC5vcmcvY29weXJpZ2h0Ij5PRGJMPC9hPi4nLAogICAgICAgICAgICAgICAgICAgIGRldGVjdFJldGluYTogZmFsc2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85NmQ5Njc4YmFiZmM0ZDQ4OWE0OTIwNDkyMDRmYWMwZSk7CgogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIHRpbGVfbGF5ZXJfNTUyYTUyOWRiZDAzNDVhMDgyYTgxODljMTg4ZDAyZWIgPSBMLnRpbGVMYXllcigKICAgICAgICAgICAgICAgICdodHRwOi8vc2VydmljZXMuYXJjZ2lzb25saW5lLmNvbS9hcmNnaXMvcmVzdC9zZXJ2aWNlc09jZWFuL1dvcmxkX09jZWFuX0Jhc2VNYXBTZXJ2ZXIvdGlsZS97en0ve3l9L3t4fScsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbWF4Wm9vbTogMTgsCiAgICAgICAgICAgICAgICAgICAgbWluWm9vbTogMSwKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGlvbjogJ0VTUkknLAogICAgICAgICAgICAgICAgICAgIGRldGVjdFJldGluYTogZmFsc2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85NmQ5Njc4YmFiZmM0ZDQ4OWE0OTIwNDkyMDRmYWMwZSk7CgogICAgICAgIAogICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIGxheWVyX2NvbnRyb2xfZDA1ZTVhYmI2ZjA1NGY5MjhhMjQ1M2ZjMDg5MzRiOTcgPSB7CiAgICAgICAgICAgICAgICBiYXNlX2xheWVycyA6IHsgIm9wZW5zdHJlZXRtYXAiIDogdGlsZV9sYXllcl84YmI4OTk0ZjQ5NzM0M2I2ODI4OTg3ZDc2NGVhOWYwOSwgfSwKICAgICAgICAgICAgICAgIG92ZXJsYXlzIDogeyAiV29ybGRfT2NlYW5fQmFzZSIgOiB0aWxlX2xheWVyXzU1MmE1MjlkYmQwMzQ1YTA4MmE4MTg5YzE4OGQwMmViLCB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICBMLmNvbnRyb2wubGF5ZXJzKAogICAgICAgICAgICAgICAgbGF5ZXJfY29udHJvbF9kMDVlNWFiYjZmMDU0ZjkyOGEyNDUzZmMwODkzNGI5Ny5iYXNlX2xheWVycywKICAgICAgICAgICAgICAgIGxheWVyX2NvbnRyb2xfZDA1ZTVhYmI2ZjA1NGY5MjhhMjQ1M2ZjMDg5MzRiOTcub3ZlcmxheXMKICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk2ZDk2NzhiYWJmYzRkNDg5YTQ5MjA0OTIwNGZhYzBlKTsKICAgICAgICAKICAgICAgICAKICAgICAgICAKICAgICAgICA8L3NjcmlwdD4KICAgICAgICA=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;\"></iframe></div></div>"
      ],
      "text/plain": [
       "<__main__.Map3d at 0x7f1a482210d0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mapa = Map3d(location=[-42, -42], tiles=None, zoom_start=2)\n",
    "mapa.add_child(TileLayer3d(tiles='OpenStreetMap'))\n",
    "\n",
    "url = ('http://services.arcgisonline.com/arcgis/rest/services'\n",
    "       'Ocean/World_Ocean_Base'\n",
    "       'MapServer/tile/{z}/{y}/{x}')\n",
    "\n",
    "folium.TileLayer(tiles=url,\n",
    "                 name='World_Ocean_Base',\n",
    "                 attr='ESRI',\n",
    "                 overlay=True).add_to(mapa)\n",
    "\n",
    "folium.LayerControl().add_to(mapa)\n",
    "\n",
    "mapa"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Iris (Python 2)",
   "language": "python",
   "name": "iris_python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
